package it.uniroma2.art.coda.imdb;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import it.uniroma2.art.owlart.exceptions.ModelAccessException;
import it.uniroma2.art.owlart.exceptions.ModelCreationException;
import it.uniroma2.art.owlart.exceptions.ModelUpdateException;
import it.uniroma2.art.owlart.exceptions.UnsupportedRDFFormatException;
import it.uniroma2.art.owlart.io.RDFFormat;
import it.uniroma2.art.owlart.model.ARTURIResource;
import it.uniroma2.art.owlart.model.NodeFilters;
import it.uniroma2.art.owlart.models.OWLArtModelFactory;
import it.uniroma2.art.owlart.models.OWLModel;
import it.uniroma2.art.owlart.models.UnloadableModelConfigurationException;
import it.uniroma2.art.owlart.models.UnsupportedModelConfigurationException;
import it.uniroma2.art.owlart.models.conf.BadConfigurationException;
import it.uniroma2.art.owlart.navigation.ARTURIResourceIterator;
import it.uniroma2.art.owlart.sesame2impl.factory.ARTModelFactorySesame2Impl;
import it.uniroma2.art.owlart.sesame2impl.models.conf.Sesame2ModelConfiguration;
import it.uniroma2.art.owlart.sesame2impl.models.conf.Sesame2PersistentInMemoryModelConfiguration;

public class OntologyTest {

	private static boolean useAutocommit;

	private static boolean useResoner;

	private String rdfInputFilePath = "imdbOnto.owl";

	private String baseUri = "http://art.uniroma2.it/imdb";
	private String importedUri = "http://art.uniroma2.it/imdb";

	private String repositoryDirPath = "repDir";

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		useAutocommit = false;
		useResoner = false;

		OWLModel owlModel = null;

		OntologyTest ontTest = new OntologyTest();

		try {
			// Create an OWLModel and the triple Store.
			owlModel = ontTest.initializeOWLModel();

			ontTest.listClasses(owlModel);
		} catch (ModelUpdateException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ModelAccessException e) {
			e.printStackTrace();
		} catch (UnsupportedRDFFormatException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (ModelCreationException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (UnsupportedModelConfigurationException e) {
			e.printStackTrace();
		} catch (UnloadableModelConfigurationException e) {
			e.printStackTrace();
		} catch (BadConfigurationException e) {
			e.printStackTrace();
		}

	}

	private OWLModel initializeOWLModel() throws ModelUpdateException, FileNotFoundException, IOException,
			ModelAccessException, UnsupportedRDFFormatException, ClassNotFoundException,
			ModelCreationException, InstantiationException, IllegalAccessException,
			UnsupportedModelConfigurationException, UnloadableModelConfigurationException,
			BadConfigurationException {

		ARTModelFactorySesame2Impl factImpl = new ARTModelFactorySesame2Impl();
		OWLArtModelFactory<Sesame2ModelConfiguration> fact = OWLArtModelFactory.createModelFactory(factImpl);
		Sesame2ModelConfiguration modelConf = factImpl
				.createModelConfigurationObject(Sesame2PersistentInMemoryModelConfiguration.class);
		if (!useResoner) {
			modelConf.directTypeInference = false;
			modelConf.rdfsInference = false;
		}

		OWLModel owlModel = fact.loadOWLModel(baseUri, repositoryDirPath, modelConf);

		owlModel.setBaseURI(baseUri);
		owlModel.setDefaultNamespace(baseUri + "#");
		// owlModel.clearRDF();
		owlModel.addRDF(new File(rdfInputFilePath), importedUri, RDFFormat.RDFXML, NodeFilters.MAINGRAPH);

		ArrayList<String> importedOntologiesList = new ArrayList<String>();
		recursiveImport(owlModel, importedOntologiesList);

		return owlModel;
	}

	private void recursiveImport(OWLModel owlModel, ArrayList<String> importedOntologiesList)
			throws ModelAccessException, FileNotFoundException, MalformedURLException, IOException,
			ModelUpdateException, UnsupportedRDFFormatException {
		ARTURIResourceIterator artUriIter = owlModel.listOntologyImports(NodeFilters.ANY, NodeFilters.ANY);
		while (artUriIter.hasNext()) {
			ARTURIResource artUriRes = artUriIter.next();
			String uriString = artUriRes.getURI();
			if (!importedOntologiesList.contains(uriString)) {
				importedOntologiesList.add(uriString);
				System.out.println("importing ontology: " + uriString);
				owlModel.addRDF(new URL(artUriRes.getURI()), importedUri, RDFFormat.RDFXML,
						NodeFilters.MAINGRAPH);
				recursiveImport(owlModel, importedOntologiesList);
			}
		}
	};

	private void listClasses(OWLModel owlModel) throws ModelAccessException, FileNotFoundException,
			MalformedURLException, IOException, ModelUpdateException, UnsupportedRDFFormatException {
		ARTURIResourceIterator artUriIter = owlModel.listNamedClasses(true, NodeFilters.ANY);
		System.out.println("classes list:");
		while (artUriIter.hasNext()) {
			ARTURIResource artUriRes = artUriIter.next();
			String uriString = artUriRes.getURI();
			if (!uriString.startsWith("http://www.w3.org/"))
				System.out.println("\t" + artUriRes.getURI());
		}

		/*
		 * artUriIter = owlModel.listOntologyImports(NodeFilters.ANY, NodeFilters.ANY);
		 * System.out.println("imported list:"); while (artUriIter.hasNext()) { ARTURIResource artUriRes =
		 * artUriIter.next(); String uriString = artUriRes.getURI(); System.out.println("\t" +
		 * artUriRes.getURI()); owlModel .addRDF(new URL(artUriRes.getURI()), importedUri, RDFFormat.RDFXML,
		 * NodeFilters.MAINGRAPH); }
		 * 
		 * artUriIter = owlModel.listNamedClasses(true, NodeFilters.ANY);
		 * System.out.println("classes list after importing all the ontology:"); while (artUriIter.hasNext())
		 * { ARTURIResource artUriRes = artUriIter.next(); String uriString = artUriRes.getURI(); if
		 * (!uriString.startsWith("http://www.w3.org/")) System.out.println("\t" + artUriRes.getURI()); }
		 */
	}
}
